package com.juicygames.framework.gamepart;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.util.Log;

import com.juicygames.framework.exception.GamePartNotFound;

public class SubPartComponent {
	private final static String LOGTAG = HandlersComponent.class.getName();

	private GamePart componentParent;
	private Map<Class<? extends GamePart>, List<? extends GamePart>> partsMap;
	
	public SubPartComponent(GamePart parent) {
		
		this.componentParent = parent;
		
		partsMap = new HashMap<Class<? extends GamePart>, List<? extends GamePart>>();
	}

	public <G extends GamePart> G addPart(G part) {
		
		Log.i(LOGTAG, "Adding GamePart " + part.toString() + " to " + componentParent.toString());
		
		Class<? extends GamePart> partClass = part.getClass();

		if (!partsMap.containsKey(partClass)) {
			
			List<GamePart> parts = new ArrayList<GamePart>();
			parts.add(part);
			partsMap.put(partClass, parts);
			
		} else {

			List<GamePart> parts = (List<GamePart>)partsMap.get(partClass);
			parts.add(part);
			
		}
		
		return part;
	}
	
	public <PartTypeParam extends GamePart> PartTypeParam getPart(Class<PartTypeParam> partClass) {
		if (!partsMap.containsKey(partClass)) {
			String errorMessage = this.getClass() + " couldn't find another part " + partClass.getName() + " on getPart(...)";
			throw new GamePartNotFound(errorMessage);
		}
		try {
			return (PartTypeParam)partsMap.get(partClass).get(0);
		} catch (IndexOutOfBoundsException e) {
			throw new RuntimeException("When getting part " + partClass.getName() + " from " + componentParent.toString()
					+ " the parts list was found but it was empty");
		}
	}
	
	public <G extends GamePart>boolean containsPart(G part) {
		Class<? extends GamePart> partClass = part.getClass();
		
		if (!partsMap.containsKey(partClass)) {
			return false;
		}
		
		List<? extends GamePart> partsFromClass = partsMap.get(partClass);
		
		return partsFromClass.contains(part);
	} 
	
	public <G extends GamePart> List<G> getParts(Class<G> partClass) {
		if (!partsMap.containsKey(partClass)) {
			return new ArrayList<G>();
		}
		
		return (List<G>)partsMap.get(partClass);
	}

}
